package com.mcp.converter.domain.rule.manager.impl;

import com.mcp.converter.domain.rule.compatibility.CompatibilityRule;
import com.mcp.converter.domain.rule.compatibility.AbstractFunctionRule;
import com.mcp.converter.domain.rule.compatibility.datatype.*;
import com.mcp.converter.domain.rule.compatibility.function.*;
import com.mcp.converter.domain.rule.conversion.ConversionRule;
import com.mcp.converter.domain.rule.conversion.datatype.*;
import com.mcp.converter.domain.rule.conversion.function.XmlFunctionsToManualReviewRule;
import com.mcp.converter.domain.rule.manager.RuleManager;
import com.mcp.converter.shared.enums.IncompatibilityType;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: zengxiong
 * @description: 规则管理实现类
 */
@Component
public class RuleManagerImpl implements RuleManager {
    private final Map<RuleType, List<Object>> ruleStore = new HashMap<>();

    public RuleManagerImpl() {
        initializeRules();
    }

    private void initializeRules() {
        // 兼容性规则-不兼容数据类型
        List<Object> compatibilityRules = new ArrayList<>();
        compatibilityRules.add(new BFileDataTypeRule());
        compatibilityRules.add(new LongDataTypeRule());
        compatibilityRules.add(new LongRawDataTypeRule());
        compatibilityRules.add(new NClobDataTypeRule());
        compatibilityRules.add(new TimestampWithTimeZoneRule());

        // 兼容性规则-不兼容内建函数(不全,需持续完善)
        compatibilityRules.add(new DateTimeFunctionRule());
        compatibilityRules.add(new EncodingDecodingFunctionRule());
        compatibilityRules.add(new EnvironmentIdentifierFunctionRule());
        compatibilityRules.add(new FirstLastValueFunctionRule());
        compatibilityRules.add(new HierarchyFunctionRule());
        compatibilityRules.add(new ListaggFunctionRule());
        compatibilityRules.add(new MiscFunctionRule());
        compatibilityRules.add(new NthValueFunctionRule());
        compatibilityRules.add(new NumberFunctionRule());
        compatibilityRules.add(new PivotUnpivotRule());
        compatibilityRules.add(new RegexpFunctionRule());
        compatibilityRules.add(new StringFunctionRule());
        compatibilityRules.add(new SystemFunctionRule());
        compatibilityRules.add(new XmlFunctionsRule());
        compatibilityRules.add(new AdvancedFunctionRule());

        // 转换规则-不兼容数据类型
        List<Object> conversionRules = new ArrayList<>();
        conversionRules.add(new BFileToBlobConversionRule());
        conversionRules.add(new LongToClobConversionRule());
        conversionRules.add(new LongRawToBlobConversionRule());
        conversionRules.add(new TimestampTzToTimestampConversionRule());

        // 转换规则-不兼容内建函数(不全,需持续完善)--暂时交给大模型自动分析,给出建议
        conversionRules.add(new XmlFunctionsToManualReviewRule());
        ruleStore.put(RuleType.COMPATIBILITY, compatibilityRules);
        ruleStore.put(RuleType.CONVERSION, conversionRules);
    }

    @Override
    public LoadResult loadRules(RuleType ruleType) {
        List<Object> rules = ruleStore.get(ruleType);
        if (rules != null && !rules.isEmpty()) {
            return new LoadResult(true, "规则加载成功", rules.size());
        }
        return new LoadResult(false, "未找到相关规则", 0);
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> List<T> queryRules(RuleType ruleType, RuleQueryCondition condition) {
        List<Object> rules = ruleStore.getOrDefault(ruleType, Collections.emptyList());

        // 应用查询条件进行过滤
        if (condition != null) {
            if (condition.getId() != null && !condition.getId().isEmpty()) {
                rules = rules.stream().filter(rule -> {
                    if (rule instanceof CompatibilityRule) {
                        return ((CompatibilityRule) rule).getId().equals(condition.getId());
                    } else if (rule instanceof ConversionRule) {
                        return ((ConversionRule) rule).getId().equals(condition.getId());
                    }
                    return false;
                }).collect(Collectors.toList());
            }

            if (condition.getName() != null && !condition.getName().isEmpty()) {
                rules = rules.stream().filter(rule -> {
                    if (rule instanceof CompatibilityRule) {
                        return ((CompatibilityRule) rule).getName().contains(condition.getName());
                    } else if (rule instanceof ConversionRule) {
                        return ((ConversionRule) rule).getName().contains(condition.getName());
                    }
                    return false;
                }).collect(Collectors.toList());
            }

            if (condition.getType() != null && !condition.getType().isEmpty()) {
                rules = rules.stream().filter(rule -> {
                    if (rule instanceof CompatibilityRule) {
                        IncompatibilityType type = ((CompatibilityRule) rule).getIncompatibilityType();
                        return type != null && type.name().equalsIgnoreCase(condition.getType());
                    } else if (rule instanceof ConversionRule) {
                        IncompatibilityType type = ((ConversionRule) rule).getIncompatibilityType();
                        return type != null && type.name().equalsIgnoreCase(condition.getType());
                    }
                    return false;
                }).collect(Collectors.toList());
            }
        }

        // 根据规则类型进行转换
        Class<T> targetType = (Class<T>) (ruleType == RuleType.COMPATIBILITY ? CompatibilityRule.class :
                ConversionRule.class);

        return rules.stream().filter(targetType::isInstance).map(rule -> (T) rule).collect(Collectors.toList());
    }

    @Override
    public UpdateResult updateRule(CompatibilityRule rule) {
        if (rule == null) {
            return new UpdateResult(false, "规则不能为空");
        }

        // 获取规则类型（需要根据具体实现判断）
        RuleType ruleType = determineRuleType(rule);

        if (ruleType == null) {
            return new UpdateResult(false, "无法确定规则类型");
        }

        List<Object> rules = ruleStore.get(ruleType);
        if (rules == null) {
            rules = new ArrayList<>();
            ruleStore.put(ruleType, rules);
        }

        // 查找是否已存在相同ID的规则
        Optional<Object> existingRule = rules.stream().filter(r -> {
            if (r instanceof CompatibilityRule && rule instanceof CompatibilityRule) {
                return ((CompatibilityRule) r).getId().equals(((CompatibilityRule) rule).getId());
            }
            return false;
        }).findFirst();

        if (existingRule.isPresent()) {
            // 替换现有规则
            int index = rules.indexOf(existingRule.get());
            rules.set(index, rule);
            return new UpdateResult(true, "规则更新成功");
        } else {
            // 添加新规则
            rules.add(rule);
            return new UpdateResult(true, "规则添加成功");
        }
    }

    /**
     * 确定规则类型（兼容性或转换规则）
     *
     * @param rule 规则实例
     * @return 规则类型
     */
    private RuleType determineRuleType(CompatibilityRule rule) {
        // 根据规则所属包或接口判断
        if (rule instanceof CompatibilityRule) {
            return RuleType.COMPATIBILITY;
        }
        return null;
    }
    
    @Override
    public Set<String> getAllIncompatibleFunctions() {
        Set<String> allIncompatibleFunctions = new HashSet<>();
        
        // 获取所有兼容性规则
        List<Object> compatibilityRules = ruleStore.get(RuleType.COMPATIBILITY);
        if (compatibilityRules != null) {
            for (Object rule : compatibilityRules) {
                // 只处理函数规则
                if (rule instanceof AbstractFunctionRule) {
                    AbstractFunctionRule functionRule = (AbstractFunctionRule) rule;
                    Set<String> functions = functionRule.getIncompatibleFunctions();
                    if (functions != null) {
                        allIncompatibleFunctions.addAll(functions);
                    }
                }
            }
        }
        
        return allIncompatibleFunctions;
    }
}